import Watcher from "./observer/watcher";
import { nextTick } from "./utils";
import { patch } from "./vdom/patch";
export function lifecycleMixin(Vue) {
  Vue.prototype._update = function (vnode) {
    console.log("_update");
    const vm = this;
    // 既有初始化又有更新
    // 表示将当前的虚拟节点保存起来
    const preVnode = vm._vnode;
    if (!preVnode) {
      // 初次渲染
      vm.$el = patch(vm.$el, vnode);
    } else {
      vm.$el = patch(preVnode, vnode);
    }
    vm._vnode = vnode;
  };

  Vue.prototype.$nextTick = nextTick;
}

export function mountComponent(vm, el) {
  // 更新函数， 数据变化后，会再次调用此函数
  let updateComponent = () => {
    // 调用render函数，生成虚拟dom
    vm._update(vm._render()); // 后续更新可以调用updateComponent方法
    // 用虚拟dom，生成真实dom
  };
  callHook(vm, "beforeMount");
  // 观察者模式  属性是 被观察 者  刷新页面 观察者
  // updateComponent();
  // 后续每个组件渲染的时候都会 有一个watcher
  new Watcher(
    vm,
    updateComponent,
    () => {
      console.log("更新视图了");
    },
    true
  );
  callHook(vm, "mounted");
}
export function callHook(vm, hook) {
  const handlers = vm.$options[hook] || [];
  for (let i = 0; i < handlers.length; i++) {
    handler[i].call(vm);
  }
}

// watcher 相当观察者。观察整个组件的属性变化响应
// 组件中模板中有属性 调用render的时候，需要通过get取值最后生成模板。
// 这个属性的关系就是一个依赖。watcher观察这个依赖的变化
// 属性变化了。通知观察者更新页面
